package io.github.uicdb.et;

import io.github.uicdb.et.entity.DefenseOrbEntity;
import io.github.uicdb.et.entity.ShadowDefenseOrbEntity;
import io.github.uicdb.et.item.curios.EnderLockItem;
import io.github.uicdb.et.item.curios.ShadowNecklaceItem;
import io.github.uicdb.et.item.weapon.ExtraDamageWeapon;
import io.github.uicdb.et.item.weapon.IExtraDamageProvider;
import io.github.uicdb.et.item_data.ItemElementData;
import io.github.uicdb.et.register.ElementalObject;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.ItemStack;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.event.entity.living.LivingDamageEvent;
import net.neoforged.neoforge.event.entity.living.LivingHealEvent;
import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
import net.neoforged.neoforge.event.entity.player.CriticalHitEvent;
import top.theillusivec4.curios.api.CuriosCapability;

import java.util.Objects;

import static io.github.uicdb.et.ModAttributes.*;

public class DamageEventHandle {
    public static void handle(IEventBus modBus, IEventBus gameBus) {
        gameBus.addListener(LivingDamageEvent.Pre.class, event -> {
            //计算易伤
            event.setNewDamage(event.getNewDamage() * (1 + safeGetPrecent(INJURE, event.getEntity())));
        });
        gameBus.addListener(LivingIncomingDamageEvent.class, event -> {
            LivingEntity entity = event.getEntity();
            var curioCap = entity.getCapability(CuriosCapability.INVENTORY);
            if (curioCap != null) {
                //受伤传送
                curioCap.findFirstCurio(s -> s.getItem() instanceof EnderLockItem).ifPresent(item -> {
                    if (entity.getRandom().nextFloat() < 0.15) {
                        event.setCanceled(true);
                        var random = entity.getRandom();
                        entity.randomTeleport(
                                entity.getX() + random.nextDouble() * 2, entity.getY() + random.nextDouble(), entity.getZ() + random.nextDouble() * 2, false
                        );
                    }
                });

            }
            //如果武器有元素附魔，则武器伤害类型改为元素伤害
            LivingEntity attacker = ModHelper.findAttacker(event.getContainer());
            if (attacker != null) {
                ItemStack weapon = attacker.getMainHandItem();
                ItemElementData data = weapon.get(ModItemDataComponents.ITEM_ELEMENT_DATA);
                if (data != null) {
                    //先计算特殊元素武器效果
                    if (weapon.getItem() instanceof IExtraDamageProvider provider) {
                        event.setAmount(event.getAmount() + provider.getExtraDamage(data, event.getEntity()));
                    }
                    ElementalObject elementalObject = data.getElement().value().getElementalObject();
                    IDamageSourceReplacement.castUse(event.getSource(), elementalObject.getDamageType(entity.level()));//转换伤害类型

                    //增幅元素伤害
                    event.setAmount(event.getAmount() * ModHelper.calculateDamageModifier(data.getElement().value(), attacker, entity));
                    //计算夜魔潜行加成
                    if (weapon.is(ModItems.NIGHT_DEMON)) {
                        float multipy = 1f;
                        if(attacker.isSprinting())
                            multipy += 1.5f;
                        if (event.getEntity() instanceof Mob mob) {
                            if (mob.getTarget() != attacker) {
                                multipy += 1f;
                            }
                        }
                        event.setAmount(event.getAmount() * multipy);
                    }
                }
                var curioCapAttacker = attacker.getCapability(CuriosCapability.INVENTORY);
                if (curioCapAttacker != null) {
                    //暗水晶额外伤害
                    curioCapAttacker.findFirstCurio(s -> s.getItem() instanceof ShadowNecklaceItem).ifPresent(item -> {
                        if (event.getContainer().getSource().typeHolder().equals(ModElements.YIN.elemental.getDamageType(entity.level())))
                            event.setAmount(event.getAmount() * 1.5f);
                    });
                }
            }
            if (entity.hasEffect(ModEffects.INJURE)) {
                event.setAmount(event.getAmount() * (1 + (Objects.requireNonNull(entity.getEffect(ModEffects.INJURE)).getAmplifier() + 1) * 0.1f));
            }

        });
        gameBus.addListener(LivingDamageEvent.Post.class, event -> {
            float def = event.getEntity().getData(ModAttachments.DEFENSE_ORB);
            var entity = event.getEntity();
            if (def > 0) {
                float r = Math.max(0, def - event.getNewDamage());
                //光岩。累计受伤移除护甲
                event.getEntity().setData(ModAttachments.DEFENSE_ORB, r);
                if (r == 0f) {
                    if (entity.getAttributes().hasAttribute(Attributes.ARMOR)) {
                        var a = entity.getAttributes().getInstance(Attributes.ARMOR);
                        if (a != null) {
                            a.removeModifier(DefenseOrbEntity.modifierId);
                        }
                    }
                }
            }
            //反转光岩，累计攻击移除护甲缺失
            var attacker = ModHelper.findAttacker(event.getSource());
            if (attacker != null) {
                float data = attacker.getData(ModAttachments.DEFENSE_ORB_SHADOW);
                if (data > 0) {
                    float r = Math.max(0, data - event.getNewDamage());
                    if (r == 0f) {
                        if (entity.getAttributes().hasAttribute(Attributes.ARMOR)) {
                            var a = entity.getAttributes().getInstance(Attributes.ARMOR);
                            if (a != null) {
                                a.removeModifier(ShadowDefenseOrbEntity.modifierIdShadow);
                            }
                        }
                    }
                }
                float health_getter = ModAttributes.safeGet(HEALTH_GETTER, attacker);
                if (health_getter > 0) {
                    attacker.heal(event.getNewDamage() * (1+health_getter));
                    //吸血
                }

            }

        });
        gameBus.addListener(EventPriority.LOWEST, CriticalHitEvent.class, event -> {
            ModHelper.findCurios(event.getEntity(), s -> s.is(ModItems.MAPLE_SORROW.get()), (entity, iCuriosItemHandler) -> {
                //枫之哀伤必定暴击
                event.setCriticalHit(true);
                event.setDamageMultiplier(1.5f);
            });
        });
        gameBus.addListener(LivingHealEvent.class, event -> {
            float health_recovery = ModAttributes.safeGet(HEALTH_RECOVERY, event.getEntity());
            if (health_recovery > 0) {
                event.setAmount(event.getAmount() * (1+health_recovery));
                //回复效率
            }
        });
        gameBus.addListener(EventPriority.LOWEST, LivingIncomingDamageEvent.class, event -> ModHelper.findCurios(event.getEntity(), s -> s.is(ModItems.WHEAT_WAVE.get()), (entity, iCuriosItemHandler) -> {
            if (entity.getRandom().nextFloat() < 0.5f && event.getAmount() >= entity.getMaxHealth()) {//免疫死亡，但是减少属性
                if (!event.getSource().is(DamageTypes.GENERIC_KILL)) {
                    event.setCanceled(true);
                    event.getEntity().setHealth(1);
                    entity.addEffect(
                            new MobEffectInstance(ModEffects.SERIOUS_INJURY, 20 * 60 * 60, 0)
                    );
                }
            }
        }));
    }

}
